/* $RCSFile: CheckBoxListDataType.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/ADNCRM.Core/UI/DataTypes/CheckBoxListDataType.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:29  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.IO;
using System.ComponentModel;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.Globalization;

using AddonNice.UI;
using AddonNice.Diagnostics;
using AddonNice.UI.WebControls;
using AddonNice.Configuration;

using Trace2 = System.Diagnostics.Trace;

namespace AddonNice.UI.DataTypes
{
	/// <summary>
	/// CheckBoxListDataType
	/// Implements a checkboxlist that allows multiple selections 
	/// (returns a colon-delimited string)
	/// </summary>
	public class CheckBoxListDataType : BaseDataType
	{
		private string _dataValueField;
		private string _dataTextField;

		public CheckBoxListDataType(object _dataSource, string _textField, string _dataField)  
		{
			InnerDataType       =   PropertiesDataType.List;
			InnerDataSource     =   _dataSource;
			DataTextField       =   _textField;
			DataValueField      =   _dataField;
			Ok4Validators       =   false;
		}

		protected override void InitializeComponents()
		{
            if ( DataTypeTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CheckBoxListDataType InitializeComponents BEG ReadOnly: {0}",ReadOnly),DataTypeTraceSwitch.Sw.Info);
			CheckBoxList cbl    =   new CheckBoxList();
			cbl.Width           =   new Unit("100%");
			cbl.RepeatColumns   =   2;
			cbl.DataSource      =   DataSource;
			cbl.DataValueField  =   DataValueField;
			cbl.DataTextField   =   DataTextField;
            if (HandleChanges && !cbl.AutoPostBack)
            {
                cbl.AutoPostBack            =   true;
                cbl.SelectedIndexChanged    +=  new EventHandler(cb_SelectedIndexChanged);
            }
			innerControl        =   cbl;
            if ( ReadOnly )
                cbl.Enabled     =   false;
            _IsInitialized      =   true;
		}
		        
        void cb_SelectedIndexChanged(object sender, EventArgs e)
        {
    		if ( DataTypeTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CheckBoxListDataType cd_SelectedIndexChanged sender: {0}",sender),DataTypeTraceSwitch.Sw.Info);
            string oldValue         =   Val;
            ReadDataFromEditControl();
            string newValue         =   Val;
            OnDataTypeEvent(new DataTypeEventArgs(DataTypeEventType.Changed,sender,e,oldValue,newValue));
        }

        public override string DataValueField
		{
			get
			{
				return _dataValueField;
			}
			set
			{
				_dataValueField = value;
			}
		}

		public override string DataTextField
		{
			get
			{
				return _dataTextField;
			}
			set
			{
				_dataTextField = value;
			}
		}
        
		public override object DataSource
		{
			get
			{
				return InnerDataSource;
			}
			set
			{
				InnerDataSource = value;
			}
		}


		public override string Val
		{
			get
			{
				return innerValue;
			}
			set
			{
				innerValue = value.TrimEnd(new char[] {';'}); //Remove trailing ';'
			}
		}
		
        public override void DataBind()
        {
			try
			{
				CheckBoxList cbl = (CheckBoxList) innerControl;
                cbl.Items.Clear();
				cbl.ClearSelection();
   				cbl.DataBind();
				string[] values = innerValue.Split(new char[] {';'},StringSplitOptions.RemoveEmptyEntries);
				foreach (string _value in values)
				{
					if (cbl.Items.FindByValue(_value) != null)
						cbl.Items.FindByValue(_value).Selected = true;
				}
			}
			catch (Exception ex)
			{
                if ( DataTypeTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CheckBoxListDataType DataBind ex: {0}",ex),DataTypeTraceSwitch.Sw.Info);
                throw;
			}
        }

         /// <summary>
        /// Update value from control: used by eventhandler after a control change event triggered
        /// </summary>
        /// <returns></returns>
        public override  string ReadDataFromEditControl()
		{
            Control Ctl =   EditControl;
            if (DataTypeTraceSwitch.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CheckBoxListDataType ReadDataFromEditControl BEG Control is null: {0}, Val: {1}.", (Ctl == null), Val ), DataTypeTraceSwitch.Sw.Info);
            if ( Ctl ==   null )
                return Val;
            // DO NOT use Val but use InnerValue which do a DataBind on set
			if( Ctl is  CheckBoxList)
			{
			    CheckBoxList cbl    =   (CheckBoxList)Ctl;
				StringBuilder sb    =  new StringBuilder();
				for (int i = 0 ; i < cbl.Items.Count ; i++)
				{
					if (cbl.Items[i].Selected)
					{
						sb.Append(cbl.Items[i].Value);
						sb.Append(";");
					}
				}
                innerValue = sb.ToString().TrimEnd(new char[] {';'}); //Remove trailing ';'
            }
            if (DataTypeTraceSwitch.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]BaseDataType CheckBoxListDataType END InnerValue: {0}.", innerValue), DataTypeTraceSwitch.Sw.Info);
            return Val;
        }
        
       public override Control EditControl
		{
			get
			{
				if ( innerControl == null )
					InitializeComponents();
				return innerControl;
			}
			set
			{
				if( value is  CheckBoxList)
				{
					innerControl = value;

					//Update value from control
				    CheckBoxList cbl    =   (CheckBoxList) innerControl;
                    cbl.DataValueField   =  DataValueField;
                    cbl.DataTextField    =  DataTextField;
                    if (HandleChanges && !cbl.AutoPostBack)
                    {
                        cbl.AutoPostBack         = true;
                        cbl.SelectedIndexChanged  += new EventHandler(cb_SelectedIndexChanged);
                    }
					StringBuilder sb = new StringBuilder();
					for (int i = 0 ; i < cbl.Items.Count ; i++)
					{
						if (cbl.Items[i].Selected)
						{
							sb.Append(cbl.Items[i].Value);
							sb.Append(";");
						}
					}
                    innerValue = sb.ToString().TrimEnd(new char[] {';'}); //Remove trailing ';'
                    return;
				}
                string msg  =   "[E]CheckBoxListDataType EditControl a CheckBoxList value is required, a '" + value.GetType().Name + "' is given.";
                if ( DataTypeTraceSwitch.Sw.TraceError )
                        Trace2.WriteLine(msg,DataTypeTraceSwitch.Sw.Info);
				throw new ArgumentException(msg);
			}
		}
	}
}